home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / proc / procStubs.c < prev    next >
C/C++ Source or Header  |  1991-07-29  |  27KB  |  1,193 lines

  1. /* 
  2.  * procStubs.c --
  3.  *
  4.  *    Stubs for Unix compatible system calls.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /sprite/src/kernel/proc/RCS/procStubs.c,v 1.4 91/07/29 14:25:47 shirriff Exp $";
  18. #endif /* not lint */
  19.  
  20. #define MACH_UNIX_COMPAT
  21.  
  22. #include <sprite.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <status.h>
  26. #include <errno.h>
  27. #include <procUnixStubs.h>
  28. #include <user/sys/types.h>
  29. #include <user/sys/wait.h>
  30. #include <user/sys/time.h>
  31. #include <user/sys/resource.h>
  32. #include <mach.h>
  33. #include <proc.h>
  34. #include <procInt.h>
  35. #include <vm.h>
  36. #include <fsutil.h>
  37. #include <assert.h>
  38.  
  39. int debugProcStubs;
  40.  
  41. #if defined(ds3100) || defined(ds5000)
  42. extern Mach_State *machCurStatePtr;
  43. #endif
  44.  
  45. /*
  46.  *----------------------------------------------------------------------
  47.  *
  48.  * copyin --
  49.  *
  50.  *    Copys a string from user space.
  51.  *
  52.  * Results:
  53.  *    Returns string.
  54.  *
  55.  * Side effects:
  56.  *    Copies the string.
  57.  *     
  58.  *
  59.  *----------------------------------------------------------------------
  60.  */
  61. static char *
  62. copyin(string)
  63.     char *string;
  64. {
  65.     static char buf[FS_MAX_PATH_NAME_LENGTH + 1];
  66.     int x;
  67.  
  68.     assert(debugProcStubs);
  69.     Fsutil_StringNCopy(FS_MAX_PATH_NAME_LENGTH, string, buf, &x);
  70.     return buf;
  71. }
  72.  
  73. /*
  74.  *----------------------------------------------------------------------
  75.  *
  76.  * Proc_ExitStub --
  77.  *
  78.  *    The stub for the "exit" Unix system call.
  79.  *
  80.  * Results:
  81.  *    Returns -1 on failure.
  82.  *
  83.  * Side effects:
  84.  *    Side effects associated with the system call.
  85.  *     
  86.  *
  87.  *----------------------------------------------------------------------
  88.  */
  89. int
  90. Proc_ExitStub(arg0)
  91.     int arg0;
  92. {
  93.  
  94.     if (debugProcStubs) {
  95.     printf("Proc_ExitStub(0x%x)\n", arg0);
  96.     }
  97.     Proc_Exit(arg0);
  98.     return -1;
  99. }
  100. /*
  101.  *----------------------------------------------------------------------
  102.  *
  103.  * Proc_ForkStub --
  104.  *
  105.  *    The stub for the "fork" Unix system call.
  106.  *
  107.  * Results:
  108.  *    Returns -1 on failure.
  109.  *
  110.  * Side effects:
  111.  *    Side effects associated with the system call.
  112.  *     
  113.  *
  114.  *----------------------------------------------------------------------
  115.  */
  116. int
  117. Proc_ForkStub()
  118. {
  119.     ReturnStatus    status;
  120.     Proc_PID newPid;
  121.  
  122.     if (debugProcStubs) {
  123.     printf("Proc_ForkStub\n");
  124.     }
  125. #if defined(ds3100) || defined(ds5000)
  126.     /*
  127.      * Put the right values in V1 and A3 for the child because the process
  128.      * jumps directly to user space after it is created.  A 1 in v1 
  129.      * is what the system call stub in the user process expects for the
  130.      * child.
  131.      */
  132.     machCurStatePtr->userState.regState.regs[V1] = 1;
  133.     machCurStatePtr->userState.regState.regs[A3] = 0;
  134. #else
  135.     Mach_Return2(1);
  136. #endif
  137.     status = Proc_NewProc((Address) 0, PROC_USER, FALSE, &newPid, (char *) NIL);
  138.     if (status == PROC_CHILD_PROC) {
  139.     panic("Proc_ForkStub: Child came alive here?\n");
  140.     }
  141.     if (status != SUCCESS) {
  142.     Mach_SetErrno(Compat_MapCode(status));
  143.     return -1;
  144.     }
  145. #if defined(ds3100) || defined(ds5000)
  146.     machCurStatePtr->userState.regState.regs[V1] = 0;
  147. #else
  148.     Mach_Return2(0);
  149. #endif
  150.     return (int) newPid;
  151. }
  152.  
  153. int
  154. Proc_VforkStub()
  155. {
  156.     ReturnStatus    status;
  157.     Proc_PID newPid;
  158.  
  159.     if (debugProcStubs) {
  160.     printf("Proc_VForkStub\n");
  161.     }
  162. #if defined(ds3100) || defined(ds5000)
  163.     /*
  164.      * Put the right values in V1 and A3 for the child because the process
  165.      * jumps directly to user space after it is created.  A 1 in v1 
  166.      * is what the system call stub in the user process expects for the
  167.      * child.
  168.      */
  169.     machCurStatePtr->userState.regState.regs[V1] = 1;
  170.     machCurStatePtr->userState.regState.regs[A3] = 0;
  171. #else
  172.     Mach_Return2(1);
  173. #endif
  174.     status = Proc_NewProc(0, PROC_USER, TRUE, &newPid, (char *) NIL);
  175.     if (status == PROC_CHILD_PROC) {
  176.     panic("Proc_VforkStub: Child came alive here?\n");
  177.     }
  178.     if (status != SUCCESS) {
  179.     Mach_SetErrno(Compat_MapCode(status));
  180.     return -1;
  181.     }
  182. #if defined(ds3100) || defined(ds5000)
  183.     machCurStatePtr->userState.regState.regs[V1] = 0;
  184. #else
  185.     Mach_Return2(0);
  186. #endif
  187.     return (int) newPid;
  188. }
  189.  
  190.  
  191. /*
  192.  *----------------------------------------------------------------------
  193.  *
  194.  * Proc_ExecveStub --
  195.  *
  196.  *    The stub for the "execve" Unix system call.
  197.  *
  198.  * Results:
  199.  *    Returns -1 on failure.
  200.  *
  201.  * Side effects:
  202.  *    Side effects associated with the system call.
  203.  *     
  204.  *
  205.  *----------------------------------------------------------------------
  206.  */
  207. int
  208. Proc_ExecveStub(name, argv, envp)
  209.     char *name;            /* name of file to exec */
  210.     char **argv;        /* array of arguments */
  211.     char **envp;        /* array of environment pointers */
  212. {
  213.     ReturnStatus status;
  214.  
  215.     if (debugProcStubs) {
  216.     printf("Proc_ExecveStub(%s)\n", copyin(name));
  217.     }
  218.     status = Proc_ExecEnv(name, argv, envp, FALSE);
  219.     Mach_SetErrno(Compat_MapCode(status));
  220.     return -1;
  221. }
  222.  
  223.  
  224. /*
  225.  *----------------------------------------------------------------------
  226.  *
  227.  * Proc_ExecvStub --
  228.  *
  229.  *    The stub for the "execv" Unix system call.
  230.  *
  231.  * Results:
  232.  *    Returns -1 on failure.
  233.  *
  234.  * Side effects:
  235.  *    Side effects associated with the system call.
  236.  *     
  237.  *
  238.  *----------------------------------------------------------------------
  239.  */
  240. int
  241. Proc_ExecvStub(name, argv)
  242.     char *name;            /* Name of file containing program to exec. */
  243.     char **argv;        /* Array of arguments to pass to program. */
  244. {
  245.     ReturnStatus status;
  246.  
  247.     if (debugProcStubs) {
  248.     printf("Proc_ExecvStub(%s)\n", copyin(name));
  249.     }
  250.     status = Proc_Exec(name, argv, USER_NIL, FALSE, 0);
  251.     Mach_SetErrno(Compat_MapCode(status));
  252.     return -1;
  253. }
  254.  
  255.  
  256. /*
  257.  *----------------------------------------------------------------------
  258.  *
  259.  * Proc_GetpidStub --
  260.  *
  261.  *    The stub for the "getpid" Unix system call.
  262.  *
  263.  * Results:
  264.  *    Returns -1 on failure.
  265.  *
  266.  * Side effects:
  267.  *    Side effects associated with the system call.
  268.  *     
  269.  *
  270.  *----------------------------------------------------------------------
  271.  */
  272. int
  273. Proc_GetpidStub()
  274. {
  275.  
  276.     if (debugProcStubs) {
  277.     printf("Proc_GetpidStub: %x\n", Proc_GetEffectiveProc()->processID);
  278.     }
  279.     Mach_Return2(Proc_GetEffectiveProc()->parentID);
  280.     return Proc_GetEffectiveProc()->processID;
  281. }
  282.  
  283.  
  284. /*
  285.  *----------------------------------------------------------------------
  286.  *
  287.  * Proc_GetuidStub --
  288.  *
  289.  *    The stub for the "getuid" Unix system call.
  290.  *
  291.  * Results:
  292.  *    Returns -1 on failure.
  293.  *
  294.  * Side effects:
  295.  *    Side effects associated with the system call.
  296.  *     
  297.  *
  298.  *----------------------------------------------------------------------
  299.  */
  300. int
  301. Proc_GetuidStub()
  302. {
  303.     Proc_ControlBlock *procPtr = Proc_GetEffectiveProc();
  304.     int uid,euid;
  305.  
  306.     if (debugProcStubs) {
  307.     printf("Proc_GetuidStub\n");
  308.     }
  309.     uid = procPtr->userID;
  310.     euid = procPtr->effectiveUserID;
  311.     /*
  312.      * We have to return the effective user id via Mach_Return2.
  313.      */
  314.     Mach_Return2(euid);
  315.     return uid;
  316. }
  317.  
  318.  
  319.  
  320. /*
  321.  *----------------------------------------------------------------------
  322.  *
  323.  * Proc_PtraceStub --
  324.  *
  325.  *    The stub for the "ptrace" Unix system call.
  326.  *
  327.  * Results:
  328.  *    Returns -1 on failure.
  329.  *
  330.  * Side effects:
  331.  *    Side effects associated with the system call.
  332.  *     
  333.  *
  334.  *----------------------------------------------------------------------
  335.  */
  336. /*ARGSUSED*/
  337. int
  338. Proc_PtraceStub(request, pid, addr, data)
  339.     int request, pid, *addr, data;
  340. {
  341.  
  342.     printf("ptrace is not implemented\n");
  343.     Mach_SetErrno(EINVAL);
  344.     return -1;
  345. }
  346.  
  347.  
  348. /*
  349.  *----------------------------------------------------------------------
  350.  *
  351.  * Proc_GetgidStub --
  352.  *
  353.  *    The stub for the "getgid" Unix system call.
  354.  *
  355.  * Results:
  356.  *    Returns -1 on failure.
  357.  *
  358.  * Side effects:
  359.  *    Side effects associated with the system call.
  360.  *     
  361.  *
  362.  *----------------------------------------------------------------------
  363.  */
  364. int
  365. Proc_GetgidStub()
  366. {
  367.  
  368.     /*
  369.      * The Sprite group id for Sprite at Berkeley.  Should do a better job
  370.      * of this.
  371.      */
  372.     if (debugProcStubs) {
  373.     printf("Proc_GetgidStub\n");
  374.     }
  375.     /*
  376.      * We have to return the effective group id via Mach_Return2.
  377.      */
  378.     Mach_Return2(155);
  379.     return 155;
  380. }
  381.  
  382.  
  383.  
  384. /*
  385.  *----------------------------------------------------------------------
  386.  *
  387.  * Proc_UmaskStub --
  388.  *
  389.  *    The stub for the "umask" Unix system call.
  390.  *
  391.  * Results:
  392.  *    Returns -1 on failure.
  393.  *
  394.  * Side effects:
  395.  *    Side effects associated with the system call.
  396.  *     
  397.  *
  398.  *----------------------------------------------------------------------
  399.  */
  400. int
  401. Proc_UmaskStub(newPerm)
  402.     unsigned int newPerm;
  403. {
  404.     unsigned int        oldPerm;
  405.     Proc_ControlBlock    *procPtr;
  406.  
  407.     if (debugProcStubs) {
  408.     printf("Proc_UmaskStub(0x%x)\n", newPerm);
  409.     }
  410.     procPtr = Proc_GetEffectiveProc();
  411.     oldPerm = procPtr->fsPtr->filePermissions;
  412.     procPtr->fsPtr->filePermissions = ~newPerm & 0777;
  413.     return ~oldPerm & 0x777;
  414. }
  415.  
  416.  
  417.  
  418. /*
  419.  *----------------------------------------------------------------------
  420.  *
  421.  * Proc_GetgroupsStub --
  422.  *
  423.  *    The stub for the "getgroups" Unix system call.
  424.  *
  425.  * Results:
  426.  *    Returns -1 on failure.
  427.  *
  428.  * Side effects:
  429.  *    Side effects associated with the system call.
  430.  *     
  431.  *
  432.  *----------------------------------------------------------------------
  433.  */
  434. int
  435. Proc_GetgroupsStub(gidsetlen, gidset)
  436.     int gidsetlen;
  437.     int *gidset;
  438. {
  439.     int trueGidlen;
  440.     register    Fs_ProcessState     *fsPtr;
  441.  
  442.     if (debugProcStubs) {
  443.     printf("Proc_GetgroupsStub\n");
  444.     }
  445.     fsPtr = (Proc_GetEffectiveProc())->fsPtr;
  446.  
  447.     if (gidsetlen < 0) {
  448.     Mach_SetErrno(EINVAL);
  449.     return -1;
  450.     }
  451.     trueGidlen = gidsetlen < fsPtr->numGroupIDs ? gidsetlen:fsPtr->numGroupIDs;
  452.     if (trueGidlen > 0 && gidset != USER_NIL) {
  453.     if (Proc_ByteCopy(FALSE, trueGidlen * sizeof(int),
  454.                       (Address) fsPtr->groupIDs,
  455.               (Address) gidset) != SUCCESS) {
  456.             Mach_SetErrno(EFAULT);
  457.         return -1;
  458.     }
  459.     }
  460.     return trueGidlen;
  461. }
  462.  
  463.  
  464. /*
  465.  *----------------------------------------------------------------------
  466.  *
  467.  * Proc_SetgroupsStub --
  468.  *
  469.  *    The stub for the "setgroups" Unix system call.
  470.  *
  471.  * Results:
  472.  *    Returns -1 on failure.
  473.  *
  474.  * Side effects:
  475.  *    Side effects associated with the system call.
  476.  *     
  477.  *
  478.  *----------------------------------------------------------------------
  479.  */
  480. int
  481. Proc_SetgroupsStub(ngroups, gidset)
  482.     int ngroups;
  483.     int *gidset;
  484. {
  485.     ReturnStatus status;
  486.  
  487.     if (debugProcStubs) {
  488.     printf("Proc_SetgroupsStub\n");
  489.     }
  490.     status = Proc_SetGroupIDs(ngroups, gidset);
  491.     if (status != SUCCESS) {
  492.     Mach_SetErrno(Compat_MapCode(status));
  493.     return -1;
  494.     }
  495.     return 0;
  496. }
  497.  
  498.  
  499. /*
  500.  *----------------------------------------------------------------------
  501.  *
  502.  * Proc_GetpgrpStub --
  503.  *
  504.  *    The stub for the "getpgrp" Unix system call.
  505.  *
  506.  * Results:
  507.  *    Returns -1 on failure.
  508.  *
  509.  * Side effects:
  510.  *    Side effects associated with the system call.
  511.  *     
  512.  *
  513.  *----------------------------------------------------------------------
  514.  */
  515. int
  516. Proc_GetpgrpStub(pid)
  517.     Proc_PID    pid;
  518. {
  519.     ReturnStatus        status;
  520.     Proc_PID            familyID;
  521.     Proc_ControlBlock     *procPtr;
  522.  
  523.     if (debugProcStubs) {
  524.     printf("Proc_GetpgrpStub\n");
  525.     }
  526.     if (pid == 0 || pid == PROC_MY_PID) {
  527.     procPtr = Proc_GetEffectiveProc();
  528.     Proc_Lock(procPtr);
  529.     } else {
  530.     /*
  531.      *   Get the PCB entry for the given process.
  532.      */
  533.     procPtr = Proc_LockPID(pid);
  534.     status = SUCCESS;
  535.     if (procPtr == (Proc_ControlBlock *) NIL) {
  536.         status = PROC_INVALID_PID;
  537.     } else if (!Proc_HasPermission(procPtr->effectiveUserID)) {
  538.         Proc_Unlock(procPtr);
  539.         status = PROC_UID_MISMATCH;
  540.     }
  541.     if (status != SUCCESS) {
  542.         Mach_SetErrno(Compat_MapCode(status));
  543.         return -1;
  544.     }
  545.     }
  546.     familyID = procPtr->familyID;
  547.     Proc_Unlock(procPtr);
  548.     return familyID;
  549. }
  550.  
  551.  
  552. /*
  553.  *----------------------------------------------------------------------
  554.  *
  555.  * Proc_SetpgrpStub --
  556.  *
  557.  *    The stub for the "setpgrp" Unix system call.
  558.  *
  559.  * Results:
  560.  *    Returns -1 on failure.
  561.  *
  562.  * Side effects:
  563.  *    Side effects associated with the system call.
  564.  *     
  565.  *
  566.  *----------------------------------------------------------------------
  567.  */
  568. int
  569. Proc_SetpgrpStub(pid, pgrp)
  570.     int pid;
  571.     int pgrp;
  572. {
  573.     ReturnStatus status;
  574.  
  575.     if (debugProcStubs) {
  576.     printf("Proc_SetpgrpStub\n");
  577.     }
  578.     if (pid == 0) {
  579.     pid = PROC_MY_PID;
  580.     }
  581.     status = Proc_SetFamilyID(pid, pgrp);
  582.     if (status != SUCCESS) {
  583.     Mach_SetErrno(Compat_MapCode(status));
  584.     return -1;
  585.     }
  586.     return 0;
  587. }
  588.  
  589.  
  590. /*
  591.  *----------------------------------------------------------------------
  592.  *
  593.  * Proc_Wait4Stub --
  594.  *
  595.  *    The stub for the "wait4" Unix system call.
  596.  *
  597.  * Results:
  598.  *    Returns -1 on failure.
  599.  *
  600.  * Side effects:
  601.  *    Side effects associated with the system call.
  602.  *     
  603.  *
  604.  *----------------------------------------------------------------------
  605.  */
  606. int
  607. Proc_Wait4Stub(pid, statusPtr, options, unixRusagePtr)
  608.     int            pid;
  609.     union    wait    *statusPtr;
  610.     int            options;
  611.     struct    rusage    *unixRusagePtr;
  612. {
  613.     ReturnStatus        status;
  614.     int                    flags;
  615.     union wait          waitStatus;
  616.     struct    rusage    unixRusage;
  617.     Proc_ControlBlock    *curProcPtr;
  618.     ProcChildInfo    childInfo;
  619.     Proc_ResUsage     resUsage;
  620.     extern ReturnStatus DoWait();
  621.     extern ReturnStatus Compat_SpriteSignalToUnix();
  622.     int            numPids = 0;
  623.     Proc_PID        *pidArray = 0;
  624.  
  625.     if (debugProcStubs) {
  626.     printf("Proc_Wait4Stub(%x, %x, %x, %x)\n", pid, statusPtr, options,
  627.         unixRusagePtr);
  628.     }
  629.  
  630.     if (pid<0) {
  631.     printf("Proc_Wait4Stub: wait on pgrp not implemented\n");
  632.     Mach_SetErrno(EINVAL);
  633.     return -1;
  634.     } else if (pid != 0) {
  635.     pidArray = (Proc_PID *)&pid;
  636.     numPids = 1;
  637.     }
  638.  
  639.     flags = 0;
  640.     if (!(options & WNOHANG)) {
  641.     flags |= PROC_WAIT_BLOCK;
  642.     }
  643.     if (options & WUNTRACED) {
  644.     flags |= PROC_WAIT_FOR_SUSPEND;
  645.     }
  646.     curProcPtr = Proc_GetCurrentProc();
  647.     if (curProcPtr->genFlags & PROC_FOREIGN) {
  648.     status = ProcRemoteWait(curProcPtr, flags, numPids,
  649.                             pidArray, &childInfo);
  650.     } else {
  651.     status = DoWait(curProcPtr, flags, numPids, pidArray, &childInfo);
  652.     }
  653.  
  654.     if (debugProcStubs) {
  655.     printf("Proc_Wait4Stub: status = %x, child pid = %x, status = %x, code = %x\n",
  656.         status, childInfo.processID,  childInfo.termStatus,
  657.         childInfo.termCode);
  658.     }
  659.  
  660.     if (status == GEN_ABORTED_BY_SIGNAL) {
  661.     if (debugProcStubs) {
  662.         printf("Wait interrupted by signal\n");
  663.     }
  664.     curProcPtr->unixProgress = PROC_PROGRESS_RESTART;
  665.     return 0;
  666.     } else if (status != SUCCESS) {
  667.     if (status == PROC_NO_EXITS && (options & WNOHANG)) {
  668.         if (debugProcStubs) {
  669.         printf("Proc_Wait4Stub: exiting\n");
  670.         }
  671.         return 0;
  672.     }
  673.     Mach_SetErrno(ECHILD);
  674.     return -1;
  675.     }
  676.     if (statusPtr != NULL)  {
  677.     int    unixSignal;
  678.  
  679.     waitStatus.w_status = 0;
  680.     if (childInfo.termReason == PROC_TERM_SUSPENDED) {
  681.         (void)Compat_SpriteSignalToUnix(childInfo.termStatus, &unixSignal);
  682.         waitStatus.w_stopval = WSTOPPED;
  683.         waitStatus.w_stopsig = unixSignal;
  684.     } else if (childInfo.termReason == PROC_TERM_SIGNALED ||
  685.            childInfo.termReason == PROC_TERM_RESUMED) {
  686.         (void)Compat_SpriteSignalToUnix(childInfo.termStatus, &unixSignal);
  687.         waitStatus.w_termsig = unixSignal;
  688.         /* NEED TO HANDLE coredump FIELD */
  689.     } else {
  690.         waitStatus.w_retcode = childInfo.termStatus;
  691.     }
  692.     status = Vm_CopyOut(sizeof(waitStatus), (Address)&waitStatus,
  693.                 (Address)statusPtr);
  694.     if (status != SUCCESS) {
  695.         Mach_SetErrno(EFAULT);
  696.         return -1;
  697.     }
  698.     }
  699.     if (unixRusagePtr != NULL) {
  700.     Time totalKTime;
  701.     Time totalUTime;
  702.  
  703.     /*
  704.      * Convert the usages from the internal Timer_Ticks format
  705.      * into the external Time format.
  706.      */
  707.     Timer_TicksToTime(childInfo.kernelCpuUsage, &resUsage.kernelCpuUsage);
  708.     Timer_TicksToTime(childInfo.userCpuUsage, &resUsage.userCpuUsage);
  709.     Timer_TicksToTime(childInfo.childKernelCpuUsage, 
  710.                       &resUsage.childKernelCpuUsage);
  711.         Timer_TicksToTime(childInfo.childUserCpuUsage,
  712.                   &resUsage.childUserCpuUsage);
  713.     resUsage.numQuantumEnds = childInfo.numQuantumEnds;
  714.     resUsage.numWaitEvents = childInfo.numWaitEvents;
  715.     /*
  716.      * Return the total time used by the process and all its children.
  717.      */
  718.     bzero((char *) &unixRusage, sizeof(*unixRusagePtr));
  719.     Time_Add(resUsage.userCpuUsage, resUsage.childUserCpuUsage,
  720.                         &totalUTime);
  721.     Time_Add(resUsage.kernelCpuUsage,
  722.          resUsage.childKernelCpuUsage, &totalKTime);
  723.     unixRusage.ru_utime.tv_sec = totalUTime.seconds;
  724.     unixRusage.ru_utime.tv_usec = totalUTime.microseconds;
  725.     unixRusage.ru_stime.tv_sec = totalKTime.seconds;
  726.     unixRusage.ru_stime.tv_usec = totalKTime.microseconds;
  727.     unixRusage.ru_nvcsw = resUsage.numWaitEvents;
  728.     unixRusage.ru_nivcsw = resUsage.numQuantumEnds;
  729.     status = Vm_CopyOut(sizeof(unixRusage), (Address)&unixRusage,
  730.                 (Address)unixRusagePtr);
  731.     if (status != SUCCESS) {
  732.         Mach_SetErrno(EFAULT);
  733.         return -1;
  734.     }
  735.     }
  736.     if (debugProcStubs) {
  737.     printf("Proc_Wait4Stub: returning %x\n", childInfo.processID);
  738.     }
  739.     Mach_Return2(*(int *)&waitStatus);
  740.     return childInfo.processID;
  741. }
  742.  
  743.  
  744.  
  745. /*
  746.  *----------------------------------------------------------------------
  747.  *
  748.  * Proc_SetpriorityStub --
  749.  *
  750.  *    The stub for the "setpriority" Unix system call.
  751.  *
  752.  * Results:
  753.  *    Returns -1 on failure.
  754.  *
  755.  * Side effects:
  756.  *    Side effects associated with the system call.
  757.  *     
  758.  *
  759.  *----------------------------------------------------------------------
  760.  */
  761. /*ARGSUSED*/
  762. int
  763. Proc_SetpriorityStub(which, who, prio)
  764.     int which, who, prio;
  765. {
  766.  
  767.     printf("Proc_Setpriority not implemented\n");
  768.     return 0;
  769. }
  770.  
  771.  
  772. /*
  773.  *----------------------------------------------------------------------
  774.  *
  775.  * Proc_GetpriorityStub --
  776.  *
  777.  *    The stub for the "getpriority" Unix system call.
  778.  *
  779.  * Results:
  780.  *    Returns -1 on failure.
  781.  *
  782.  * Side effects:
  783.  *    Side effects associated with the system call.
  784.  *     
  785.  *
  786.  *----------------------------------------------------------------------
  787.  */
  788. /*ARGSUSED*/
  789. int
  790. Proc_GetpriorityStub(which, who, prio)
  791.     int which, who, prio;
  792. {
  793.  
  794.     printf("Proc_GetpriorityStub not implemented\n");
  795.     return 0;
  796. }
  797.  
  798.  
  799.  
  800. /*
  801.  *----------------------------------------------------------------------
  802.  *
  803.  * Proc_SetreuidStub --
  804.  *
  805.  *    The stub for the "setreuid" Unix system call.
  806.  *
  807.  * Results:
  808.  *    Returns -1 on failure.
  809.  *
  810.  * Side effects:
  811.  *    Side effects associated with the system call.
  812.  *     
  813.  *
  814.  *----------------------------------------------------------------------
  815.  */
  816. int
  817. Proc_SetreuidStub(userID, effUserID)
  818.     int     userID;
  819.     int     effUserID;
  820. {
  821.     ReturnStatus    status;
  822.     Proc_ControlBlock     *procPtr;
  823.  
  824.     if (debugProcStubs) {
  825.     printf("Proc_SetreuidStub\n");
  826.     }
  827.     procPtr = Proc_GetEffectiveProc();
  828.     if (userID == -1 || userID == PROC_NO_ID) {
  829.     userID = procPtr->userID;;
  830.     }
  831.     if (effUserID == -1 || effUserID == PROC_NO_ID) {
  832.     effUserID = procPtr->effectiveUserID;
  833.     }
  834.     if (userID != procPtr->userID && userID != procPtr->effectiveUserID &&
  835.     procPtr->effectiveUserID != PROC_SUPER_USER_ID) {
  836.     Mach_SetErrno(Compat_MapCode(PROC_UID_MISMATCH));
  837.     return -1;
  838.     }
  839.     if (effUserID != procPtr->userID && effUserID != procPtr->effectiveUserID &&
  840.     procPtr->effectiveUserID != PROC_SUPER_USER_ID) {
  841.     Mach_SetErrno(Compat_MapCode(PROC_UID_MISMATCH));
  842.     return -1;
  843.     }
  844.     procPtr->userID = userID;
  845.     procPtr->effectiveUserID = effUserID;
  846.     if (procPtr->state == PROC_MIGRATED) {
  847.     status = Proc_MigUpdateInfo(procPtr);
  848.     if (status != SUCCESS) {
  849.         Mach_SetErrno(Compat_MapCode(status));
  850.         return -1;
  851.     }
  852.     }
  853.     return 0;
  854. }
  855.  
  856.  
  857.  
  858. /*
  859.  *----------------------------------------------------------------------
  860.  *
  861.  * Proc_SetregidStub --
  862.  *
  863.  *    The stub for the "setregid" Unix system call.
  864.  *
  865.  * Results:
  866.  *    Returns -1 on failure.
  867.  *
  868.  * Side effects:
  869.  *    Side effects associated with the system call.
  870.  *     
  871.  *
  872.  *----------------------------------------------------------------------
  873.  */
  874. int
  875. Proc_SetregidStub(rgid, egid)
  876.     int    rgid, egid;
  877. {
  878.     int        array[2];
  879.     int        num = 0;
  880.     Proc_ControlBlock     *procPtr;
  881.     Fs_ProcessState     *fsPtr;
  882.     int i;
  883.  
  884.     if (debugProcStubs) {
  885.     printf("Proc_SetregidStub\n");
  886.     }
  887.     if (rgid != -1) {
  888.     array[0] = rgid;
  889.     num = 1;
  890.     if (egid != rgid && egid != -1) {
  891.         array[1] = egid;
  892.         num++;
  893.     }
  894.     } else if (egid != -1) {
  895.     array[0] = egid;
  896.     num++;
  897.     }
  898.     if (num > 0) {
  899.     /*
  900.      * Need to protect against abritrary group setting.
  901.      */
  902.     procPtr = Proc_GetEffectiveProc();
  903.     if (procPtr->effectiveUserID != 0) {
  904.         Mach_SetErrno(EPERM);
  905.         return -1;
  906.     }
  907.  
  908.     /*
  909.      *  If the current group ID table is too small, allocate space
  910.      *    for a larger one.
  911.      */
  912.     fsPtr = procPtr->fsPtr;
  913.     if (fsPtr->numGroupIDs < num) {
  914.         free((Address) fsPtr->groupIDs);
  915.         fsPtr->groupIDs = (int *) malloc(num * sizeof(int));
  916.     }
  917.     for (i = 0; i < num; i++) {
  918.         fsPtr->groupIDs[i] = array[i];
  919.     }  
  920.     fsPtr->numGroupIDs = num;
  921.     }
  922.     return 0;
  923. }
  924.  
  925.  
  926.  
  927. /*
  928.  *----------------------------------------------------------------------
  929.  *
  930.  * Proc_GetrlimitStub --
  931.  *
  932.  *    The stub for the "getrlimit" Unix system call.
  933.  *
  934.  * Results:
  935.  *    Returns -1 on failure.
  936.  *
  937.  * Side effects:
  938.  *    Side effects associated with the system call.
  939.  *     
  940.  *
  941.  *----------------------------------------------------------------------
  942.  */
  943. int
  944. Proc_GetrlimitStub()
  945. {
  946.  
  947.     printf("Proc_Getrlimit not implemented\n");
  948.     return 0;
  949. }
  950.  
  951.  
  952. /*
  953.  *----------------------------------------------------------------------
  954.  *
  955.  * Proc_SetrlimitStub --
  956.  *
  957.  *    The stub for the "setrlimit" Unix system call.
  958.  *
  959.  * Results:
  960.  *    Returns -1 on failure.
  961.  *
  962.  * Side effects:
  963.  *    Side effects associated with the system call.
  964.  *     
  965.  *
  966.  *----------------------------------------------------------------------
  967.  */
  968. int
  969. Proc_SetrlimitStub()
  970. {
  971.  
  972.     printf("Proc_Setrlimit not implemented\n");
  973.     return 0;
  974. }
  975.  
  976.  
  977. #define COPYTIME(TO,FROM) { \
  978.         (TO).tv_sec = (FROM).seconds; \
  979.         (TO).tv_usec = (FROM).microseconds; \
  980.       }
  981.  
  982.  
  983. /*
  984.  *----------------------------------------------------------------------
  985.  *
  986.  * Proc_GetrusageStub --
  987.  *
  988.  *    The stub for the "getrusage" Unix system call.
  989.  *
  990.  * Results:
  991.  *    Returns -1 on failure.
  992.  *
  993.  * Side effects:
  994.  *    Side effects associated with the system call.
  995.  *     
  996.  *
  997.  *----------------------------------------------------------------------
  998.  */
  999. int
  1000. Proc_GetrusageStub(who, rusage)
  1001.     int who;
  1002.     struct rusage *rusage;
  1003. {
  1004.     Proc_ResUsage spriteUsage;         /* sprite resource usage buffer */
  1005.     struct rusage unixUsage;
  1006.     register Proc_ControlBlock     *procPtr;
  1007.     ReturnStatus status;
  1008.  
  1009.     if (debugProcStubs) {
  1010.     printf("Proc_GetrusageStub\n");
  1011.     }
  1012.  
  1013.     procPtr = Proc_GetEffectiveProc();
  1014.     if (procPtr == (Proc_ControlBlock *) NIL) {
  1015.     panic("Proc_GetResUsage: procPtr == NIL\n");
  1016.     } 
  1017.     Proc_Lock(procPtr);
  1018.     Timer_TicksToTime(procPtr->kernelCpuUsage.ticks,
  1019.     &spriteUsage.kernelCpuUsage);
  1020.     Timer_TicksToTime(procPtr->userCpuUsage.ticks, &spriteUsage.userCpuUsage);
  1021.     Timer_TicksToTime(procPtr->childKernelCpuUsage.ticks,
  1022.     &spriteUsage.childKernelCpuUsage);
  1023.     Timer_TicksToTime(procPtr->childUserCpuUsage.ticks,
  1024.     &spriteUsage.childUserCpuUsage);
  1025.     spriteUsage.numQuantumEnds = procPtr->numQuantumEnds;
  1026.     spriteUsage.numWaitEvents     = procPtr->numWaitEvents;
  1027.     Proc_Unlock(procPtr);
  1028.     if (who == RUSAGE_SELF) {
  1029.     COPYTIME(unixUsage.ru_utime, spriteUsage.userCpuUsage);
  1030.     COPYTIME(unixUsage.ru_stime, spriteUsage.kernelCpuUsage);
  1031.     } else {
  1032.     COPYTIME(unixUsage.ru_utime, spriteUsage.childUserCpuUsage);
  1033.     COPYTIME(unixUsage.ru_stime, spriteUsage.childKernelCpuUsage);
  1034.     }
  1035.     unixUsage.ru_maxrss = 0;
  1036.     unixUsage.ru_ixrss = 0;    /* integral shared memory size */
  1037.     unixUsage.ru_idrss = 0;    /* integral unshared data size */
  1038.     unixUsage.ru_isrss = 0;    /* integral unshared stack size */
  1039.     unixUsage.ru_minflt = 0;    /* page reclaims */
  1040.     unixUsage.ru_majflt = 0;    /* page faults */
  1041.     unixUsage.ru_nswap = 0;    /* swaps */
  1042.     unixUsage.ru_inblock = 0;    /* block input operations */
  1043.     unixUsage.ru_oublock = 0;    /* block output operations */
  1044.     unixUsage.ru_msgsnd = 0;    /* messages sent */
  1045.     unixUsage.ru_msgrcv = 0;    /* messages received */
  1046.     unixUsage.ru_nsignals = 0;    /* signals received */
  1047.     unixUsage.ru_nvcsw =
  1048.         spriteUsage.numWaitEvents;  /* voluntary context switches */
  1049.     unixUsage.ru_nivcsw =
  1050.         spriteUsage.numQuantumEnds;  /* involuntary context switches */
  1051.     status = Vm_CopyOut(sizeof(unixUsage), (Address)&unixUsage, 
  1052.               (Address)rusage);
  1053.     if (status != SUCCESS) {
  1054.     Mach_SetErrno(Compat_MapCode(status));
  1055.     return -1;
  1056.     }
  1057.     return 0;
  1058. }
  1059.  
  1060.  
  1061. /*
  1062.  *----------------------------------------------------------------------
  1063.  *
  1064.  * Proc_GetitimerStub --
  1065.  *
  1066.  *    The stub for the "getitimer" Unix system call.
  1067.  *
  1068.  * Results:
  1069.  *    Returns -1 on failure.
  1070.  *
  1071.  * Side effects:
  1072.  *    Side effects associated with the system call.
  1073.  *     
  1074.  *
  1075.  *----------------------------------------------------------------------
  1076.  */
  1077. int
  1078. Proc_GetitimerStub(which, value)
  1079.     int which;
  1080.     struct itimerval *value;
  1081. {
  1082.     ReturnStatus    status;
  1083.  
  1084.     if (debugProcStubs) {
  1085.     printf("Proc_GetitimerStub\n");
  1086.     }
  1087.     status = Proc_GetIntervalTimer(which, (Proc_TimerInterval *) value);
  1088.     if (status != SUCCESS) {
  1089.     Mach_SetErrno(Compat_MapCode(status));
  1090.     return -1;
  1091.     }
  1092.     return 0;
  1093. }
  1094.  
  1095.  
  1096. /*
  1097.  *----------------------------------------------------------------------
  1098.  *
  1099.  * Proc_SetitimerStub --
  1100.  *
  1101.  *    The stub for the "setitimer" Unix system call.
  1102.  *
  1103.  * Results:
  1104.  *    Returns -1 on failure.
  1105.  *
  1106.  * Side effects:
  1107.  *    Side effects associated with the system call.
  1108.  *     
  1109.  *
  1110.  *----------------------------------------------------------------------
  1111.  */
  1112. int
  1113. Proc_SetitimerStub(which, value, ovalue)
  1114.  
  1115.     int which;
  1116.     struct itimerval *value;
  1117.     struct itimerval *ovalue;
  1118. {
  1119.     ReturnStatus    status;
  1120.  
  1121.     if (debugProcStubs) {
  1122.     printf("Proc_SetitimerStub\n");
  1123.     }
  1124.     status = Proc_SetIntervalTimer(which, (Proc_TimerInterval *) value,
  1125.                  (Proc_TimerInterval *) ovalue);
  1126.     if (status != SUCCESS) {
  1127.     Mach_SetErrno(Compat_MapCode(status));
  1128.     return -1;
  1129.     }
  1130.     return 0;
  1131. }
  1132.  
  1133. /*
  1134.  *----------------------------------------------------------------------
  1135.  *
  1136.  * Proc_Wait3Stub --
  1137.  *
  1138.  *    The stub for the "wait3" Unix system call.
  1139.  *
  1140.  * Results:
  1141.  *    Returns -1 on failure.
  1142.  *
  1143.  * Side effects:
  1144.  *    Side effects associated with the system call.
  1145.  *     
  1146.  *
  1147.  *----------------------------------------------------------------------
  1148.  */
  1149. int
  1150. Proc_Wait3Stub(statusPtr, options, unixRusagePtr)
  1151.     union    wait    *statusPtr;
  1152.     int            options;
  1153.     struct    rusage    *unixRusagePtr;
  1154. {
  1155.     if (debugProcStubs) {
  1156.     printf("Proc_Wait4Stub(%x, %x, %x)\n", statusPtr, options,
  1157.         unixRusagePtr);
  1158.     }
  1159.     return Proc_Wait4Stub(0, statusPtr, options, unixRusagePtr);
  1160. }
  1161.  
  1162. #if defined(ds3100) || defined(ds5000)
  1163. /*
  1164.  *----------------------------------------------------------------------
  1165.  *
  1166.  * Proc_WaitpidStub --
  1167.  *
  1168.  *    The stub for the "waitpid" Unix system call.
  1169.  *
  1170.  * Results:
  1171.  *    Returns -1 on failure.
  1172.  *
  1173.  * Side effects:
  1174.  *    Side effects associated with the system call.
  1175.  *     
  1176.  *
  1177.  *----------------------------------------------------------------------
  1178.  */
  1179. int
  1180. Proc_WaitpidStub(pid, statusPtr, options)
  1181.     int            pid;
  1182.     union    wait    *statusPtr;
  1183.     int            options;
  1184. {
  1185.     if (pid==-1) {
  1186.     pid = 0;
  1187.     } else if (pid==0) {
  1188.     pid = -Proc_GetpgrpStub(pid);
  1189.     }
  1190.     return Proc_Wait4Stub(pid, statusPtr, options, 0);
  1191. }
  1192. #endif
  1193.